#pragma once
#include <string>
#include <sys/stat.h>
#include <sys/time.h>
#include <atomic>
#include <fstream>
#include <vector>
#include <boost/algorithm/string.hpp>


namespace util_ns
{
    
    const static std::string temp = "./temp/";

    class Time_Util
    {
    public:
        static std::string GetTimeStamp()
        {
            struct timeval tv;

            gettimeofday(&tv, nullptr);
            return std::to_string(tv.tv_sec);
        }

        static std::string GetMsTimeStamp() // 得到毫秒级的时间戳
        {
            struct timeval tv;

            gettimeofday(&tv, nullptr); // 不关心时区

            return std::to_string(tv.tv_sec * 1000 + tv.tv_usec / 1000);
        }
    };

    class Path_Util
    {
    private:
        static std::string Spilt_Path(const std::string &filename, const std::string &suffic)
        {
            return temp + filename + suffic;
        }

    public:
        static std::string Compile_Error_Path(const std::string &filename)
        {
            return Spilt_Path(filename, ".CompileError");
        }

        static std::string Src_Path(const std::string &filename)
        {
            return Spilt_Path(filename, ".cpp");
        }

        static std::string Exe_Path(const std::string &filename)
        {
            return Spilt_Path(filename, ".exe");
        }

        static std::string Stderr_Path(const std::string &filename)
        {
            return Spilt_Path(filename, ".stderr");
        }

        static std::string Stdin_Path(const std::string &filename)
        {
            return Spilt_Path(filename, ".stdin");
        }

        static std::string Stdout_Path(const std::string &filename)
        {
            return Spilt_Path(filename, ".stdout");
        }
    };

    class File_Util
    {
    public:
        static bool Is_Exist_File(const std::string &file_name)
        {
            struct stat st;
            if (stat(file_name.c_str(), &st) == 0)
            {
                // 成功获取文件属性，说明该文件是存在的
                return true;
            }

            return false;
        }
        /**
         * 毫秒级的时间戳+原子计数器保证文件名的唯一性
         */
        static std::string UniqueFileName()
        {
            static std::atomic<int> id(0);

            std::string res = Time_Util::GetMsTimeStamp();

            res += ("_" + std::to_string(id));
            id++;

            return res;
        }

        /**
         *写入文件->将内容输出进文件
         */
        static bool WriteFile(const std::string &file_name, const std::string &content)
        {
            std::ofstream out(file_name);
            if (!out.is_open())
            {
                return false;
            }

            out.write(content.c_str(), content.size());
            out.close();

            return true;
        }

        /*
         *从文件中读取内容->将文件中的内容输入到用户缓冲区
         *
         */
        static bool ReadFile(const std::string &file_name, std::string *content, bool keep)
        {
            (*content).clear();
            std::ifstream in(file_name);

            if (!in.is_open())
            {

                return false;
            }
            std::string line;
            while (std::getline(in, line))
            {
                (*content) += line;
                (*content) += keep ? "\n" : "";
            }

            return true;
        }
    };

    class Spilt_Util
    {
    public:
        static void Split(const std::string &str, std::vector<std::string> *out, const std::string &seq)
        {
            // 调用boost库，并分割str，存入out
            boost::split(*out, str, boost::is_any_of(seq), boost::algorithm::token_compress_on);
        }
    };
}